package com.z.redis.datatype;

import com.z.redis.command.CommandType;

import java.util.Comparator;
import java.util.List;
import java.util.TreeMap;
import java.util.stream.Collectors;

public class RedisZset implements RedisData{
    private volatile long timeout = -1;
    private TreeMap <ZsetKey,Long> map = new TreeMap<>(new Comparator<ZsetKey>() {
        @Override
        public int compare(ZsetKey o1, ZsetKey o2) {
            if(o1.key.equals(o2.key)){
                return 0;
            }
            return Long.compare(o1.score, o2.score); // 按分数排序
        }
    });

    public static class ZsetKey{ // 封装数据和分数
        BytesWrapper key;
        long score;
        public ZsetKey(BytesWrapper key, long score) {
            this.key = key;
            this.score = score;
        }
        public BytesWrapper getKey() { return key; }
        public long getScore() { return score; }

        @Override
        public boolean equals(Object o) {
            return key.equals(((ZsetKey)o).key);
        }

        @Override
        public int hashCode() {
            return key.hashCode();
        }
    }

    /**
     * Zadd key score member [score member ...]
     * @param keys
     * @return 插入的元素个数
     */
    public int add(List<ZsetKey> keys){
        return (int) keys.stream().peek(key -> {
            map.put(key, key.score); // 插入或者更新分数
        }).count();
    }

    /**
     * Zrange key start end
     * @param start
     * @param end
     * @return 指定范围的元素
     */
    public List<ZsetKey> range(int start, int end){
        return map.keySet().stream()
                .skip(start)
                .limit(end - start >= 0 ? end - start + 1 : 0)
                .collect(Collectors.toList());
    }

    /**
     * Zrevrange key start stop
     * @param start
     * @param end
     * @return 指定范围的元素 并按照从大到小
     */
    public List<ZsetKey> reRange(int start, int end){
        return map.descendingKeySet().stream()
                .skip(start)
                .limit(end - start >= 0 ? end - start + 1 : 0)
                .collect(Collectors.toList());
    }

    /**
     * Zrem key member [member ...]
     * @param members
     * @return 删除的元素个数
     */
    public int remove(List<BytesWrapper> members){
        return (int)members.stream()
                .filter(member -> map.remove(new ZsetKey(member, 0)) != null)
                .count();
    }

    /**
     * zcard key
     * @return 获取有序集合的成员数
     */
    public int zcard(){
        return map.size();
    }

    @Override
    public long getTimeout() {
        return timeout;
    }

    @Override
    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }
}
